import constValue from './const';
import constVal from './const';
import DateClass from './DateClass';
import { clockFactory } from './utils';

export interface dateBase {
    isCurrent: boolean;
    title: number;
    isHolidays: boolean;
    date: string;
    lunars: string;
    lunarsChina: string;
    isNow: boolean;
    term: string | false;
    lunarsChinese: string;
    solarDay: string | false;
    animal: string;
    astro: string;
    lunarDay: string | false;
    isWeek?: boolean;
}
/**
 * 获得节气
 * @param y 农历年度
 * @param m 公立月份
 * @param d 公立日期
 * @returns
 */
export function getTerm(y: number, m: number, d: number) {
    let firstNode = DateClass.getTerm(y, m * 2 - 1),
        secondNode = DateClass.getTerm(y, m * 2);

    let term: false | string = false;

    if (Number(firstNode) === d) term = constVal.solarTerm[m * 2 - 2];
    if (Number(secondNode) == d) term = constVal.solarTerm[m * 2 - 1];

    return term;
}

class Calendar {
    title() {
        const title: string[] = [];
        for (let i = 0; i <= 6; i++) {
            title.push(constValue.nStr1[i % 7]);
        }
        return title;
    }
    validateDate(date: number[]) {
        if (date.length === 3 && String(date[0]).length === 4) {
            return date;
        } else {
            return DateClass.getCurrent();
        }
    }
    getDateParams(day: dateBase[], date: number[]) {
        return day.map((el, index) => {
            return {
                title: el.title,
                isCurrent: el.isCurrent,
                value: 'tCalendar' + new Date().getTime(),
                isWeek: new Date(el.date).getDay() === 6 || new Date(el.date).getDay() === 0,
                isHolidays: el.isHolidays,
                date: el.date,
                lunars: el.lunars,
                lunarsChinese: el.lunarsChinese,
                lunarsChina: el.lunarDay || el.solarDay || el.term || el.lunarsChina,
                isNow: el.isNow,
                animal: el.animal,
                astro: el.astro,
                term: el.term,
                solarDay: el.solarDay,
                lunarDay: el.lunarDay
            };
        });
    }
    /**
     * 获取当月前面需补齐的数组
     */
    beforDays(date: number[], last: number) {
        const y = date[1] === 1 ? date[0] - 1 : date[0];
        const m = date[1] === 1 ? 12 : date[1] - 1;
        let w = DateClass.solarMonth(y, m);

        const arr: dateBase[] = [];
        for (let i = 0; i < last; i++) {
            const lun = DateClass.getLunars(y, m, w - i);
            const l = lun.split('-');
            arr.push({
                title: w - i,
                isCurrent: false,
                isHolidays: DateClass.getHolidays([y, m, w - i]),
                date: `${y}-${clockFactory(m)}-${clockFactory(w - i)}`,
                lunars: lun,
                lunarsChinese:
                    DateClass.toChinaMonth(Number(l[1])) + DateClass.toChinaDay(Number(l[2])),
                lunarsChina: DateClass.toChinaDay(Number(l[2])),
                isNow: false,
                solarDay: DateClass.getSolarDay(m, w - i),
                lunarDay: DateClass.getlunarDay(Number(l[0]), Number(l[1]), Number(l[2])),
                animal: DateClass.getAnimal(Number(l[0])),
                astro: DateClass.toAstro(y, m, w - i),
                term: getTerm(Number(l[0]), m, w - i)
            });
        }
        return arr;
    }
    /**
     * 获取当月后面需补齐的数组
     */
    afterDays(day: dateBase[], date: number[]) {
        const arr: dateBase[] = [];
        const y = date[1] === 12 ? date[0] + 1 : date[0];
        const m = date[1] === 12 ? 1 : date[1] + 1;

        for (let i = 1; i < 42 - day.length + 1; i++) {
            const lun = DateClass.getLunars(y, m, i);
            const l = lun.split('-');
            arr.push({
                title: i,
                isCurrent: false,
                isHolidays: DateClass.getHolidays([y, m, i]),
                date: `${y}-${clockFactory(m)}-${clockFactory(i)}`,
                lunars: lun,
                lunarsChinese:
                    DateClass.toChinaMonth(Number(l[1])) + DateClass.toChinaDay(Number(l[2])),
                lunarsChina: DateClass.toChinaDay(Number(l[2])),
                isNow: false,
                solarDay: DateClass.getSolarDay(m, i),
                lunarDay: DateClass.getlunarDay(Number(l[0]), Number(l[1]), Number(l[2])),
                animal: DateClass.getAnimal(Number(l[0])),
                astro: DateClass.toAstro(y, m, i),
                term: getTerm(Number(l[0]), m, i)
            });
        }
        return [...day, ...arr];
    }
    getDay(date: number[], beforDays: dateBase[]) {
        const dateArray: dateBase[] = [];
        const currentDayNumber = DateClass.solarMonth(date[0], date[1], date[2]);
        for (let i = 1; i <= currentDayNumber; i++) {
            const lun = DateClass.getLunars(date[0], date[1], i);
            const l = lun.split('-');
            dateArray.push({
                title: i,
                isCurrent: true,
                isHolidays: DateClass.getHolidays([date[0], date[1], i]),
                date: `${date[0]}-${clockFactory(date[1])}-${clockFactory(i)}`,
                lunars: lun,
                lunarsChinese:
                    DateClass.toChinaMonth(Number(l[1])) + DateClass.toChinaDay(Number(l[2])),
                lunarsChina: DateClass.toChinaDay(Number(l[2])),
                isNow: i === date[2] ? true : false,
                solarDay: DateClass.getSolarDay(date[1], i),
                lunarDay: DateClass.getlunarDay(Number(l[0]), Number(l[1]), Number(l[2])),
                animal: DateClass.getAnimal(Number(l[0])),
                astro: DateClass.toAstro(date[0], date[1], i),
                term: getTerm(Number(l[0]), date[1], i)
            });
        }
        return [...beforDays, ...dateArray];
    }

    table(date: number[]) {
        const dateArray = [];

        const result = this.validateDate(date);

        const currentDay = DateClass.solarWeeks(result[0], result[1]);

        // 获取当月的完整数据
        const beforDays = this.beforDays(date, currentDay).reverse();

        const m = this.getDay(date, beforDays);
        const afterDays = this.afterDays(m, date);

        // 转化成参数
        const params = this.getDateParams(afterDays, date);

        // return [];
        if (params.length !== 42) return [];

        for (let row = 0; row < 6; row++) {
            dateArray.push(params.splice(0, 7));
        }
        return dateArray;
    }
}

export default new Calendar();
